﻿using System;
using System.Collections.Generic;
using RoketSolutions.SP2010.Infrostructure.UI.Ajax.Abstractions;
using RoketSolutions.SP2010.Infrostructure.UI.Ajax.Controllers;
using RoketSolutions.SP2010.Infrostructure.UI.Ajax.ModelBinders;
using RoketSolutions.SP2010.Infrostructure.UI.Ajax.ValueProviders;

namespace RoketSolutions.SP2010.Infrostructure.UI.Ajax
{
    public abstract class Bootstrapper : IBootstrapper
    {
        #region / Properties /

        List<ControllerBase> _controllers;
        public List<ControllerBase> Controllers
        {
            get
            {
                return _controllers ?? (_controllers = new List<ControllerBase>());
            }
        }

        public ControllerFactory ControllerFactory
        {
            get;
            set;
        }

        public ModelBinderDictionary ModelBinders
        {
            get;
            set;
        }

        public ValueProviderFactoryCollection ValueProviderFactories
        {
            get;
            set;
        }

        #endregion

        #region / Virtual & Abstract Methods /

        public virtual void Init(RequestContext request)
        {
            ModelBinders = ResolveModelBinders(request);
            ValueProviderFactories = ResolveValueProviderFactories(request);

            RegisterControllers(request);
            ControllerFactory = ResolveControllerFactory(request);
        }

        protected abstract void RegisterControllers(RequestContext request);

        protected virtual ControllerFactory ResolveControllerFactory(RequestContext request)
        {
            return new ControllerFactory(Controllers, ModelBinders, ValueProviderFactories);
        }

        protected virtual ModelBinderDictionary ResolveModelBinders(RequestContext request)
        {
            return new ModelBinderDictionary();
        }

        protected virtual ValueProviderFactoryCollection ResolveValueProviderFactories(RequestContext request)
        {
            var factories = new ValueProviderFactoryCollection
                                {
                                    new FormValueProviderFactory(),
                                    new QueryStringValueProviderFactory()
                                };
            return factories;
        }

        #endregion

        #region / Helper Methods /

        protected void RegisterController<T>() where T : ControllerBase, new()
        {
            var type = typeof (T);
            if (!Controllers.Exists(controller => controller.GetType() == type))
            {
                Controllers.Add(new T());
            }
            else
            {
                throw new Exception(string.Format("Controller '{0}' has already been registered", type.Name));
            }
        }

        #endregion

    }
}